﻿using UnityEngine;

namespace KuiHuaBaoDian.Services.UGUI.Tips {

    public interface ITipsUIBehaviour {

        Vector3 ButtonWorldPosition { get; }

        void Initalize(ITipsGroup group, Vector3 buttonWorldPosition, Rect buttonRect);

        void Apply();
    }

    [Implement(typeof(ITipsUIBehaviour))]
    internal sealed class KHBD_TipsUIBehaviour : KHBD_UIBehaviour, ITipsUIBehaviour {

        private KHBD_TipsUIBehaviour() : base() { }

        public Canvas Canvas { get; private set; }

        public ITipsGroup Group { get; private set; }

        public Vector3 ButtonWorldPosition { get; private set; }

        private Rect m_ButtonRect;

        private Vector3 m_LastScale = Vector3.negativeInfinity;

        private bool m_IsStart = false;

        private RectTransform m_RectTransform;
        private RectTransform RectTransform {
            get {
                if (m_RectTransform == null) {
                    m_RectTransform = gameObject.transform as RectTransform;
                }
                return m_RectTransform;
            }
        }

        //private bool m_Applied = false;

        public void Apply() {
            if (Canvas == null) {
                return;
            }

            //if (m_Applied) {
            //    m_Applied = false;
            //    return;
            //}
            //m_Applied = true;
            RectTransform.pivot = Group.Pivot;
            RectTransform.position = ButtonWorldPosition;
            var corner = new Vector2();
            if (Group.Anchor.x == 0) {
                corner.x = -m_ButtonRect.width / 2;
            } else if (Group.Anchor.x == 0.5f) {
                corner.x = 0;
            } else {
                corner.x = m_ButtonRect.width / 2;
            }
            if (Group.Anchor.y == 0) {
                corner.y = -m_ButtonRect.height / 2;
            } else if (Group.Anchor.y == 0.5f) {
                corner.y = 0;
            } else {
                corner.y = m_ButtonRect.height / 2;
            }
            RectTransform.anchoredPosition += corner + new Vector2(Group.Offset.x, Group.Offset.y);
            var localPosition = RectTransform.localPosition;
            var scale = m_LastScale = RectTransform.localScale;
            var canvasRect = (Canvas.transform as RectTransform).rect;
            var rect = RectTransform.rect;
            rect.width *= scale.x;
            rect.height *= scale.y;
            rect.x = localPosition.x - rect.width * Group.Pivot.x;
            rect.y = localPosition.y - rect.height * Group.Pivot.y;
            if (rect.xMin - Group.Margin.x < canvasRect.xMin) { // 小于左边界
                if (rect.xMax + Group.Margin.x > canvasRect.xMax) { // 同时大于右边界
                    rect.x = -rect.width / 2; // 居中
                } else {
                    rect.x = canvasRect.xMin + Group.Margin.x; // 按左边界
                }
            } else if (rect.xMax + Group.Margin.x > canvasRect.xMax) { // 大于右边界
                rect.x = canvasRect.xMax - Group.Margin.x - rect.width; // 按右边界
            }
            if (rect.yMin - Group.Margin.y < canvasRect.yMin) { // 参考x轴
                if (rect.yMax + Group.Margin.y > canvasRect.yMax) {
                    rect.y = -rect.height / 2;
                } else {
                    rect.y = canvasRect.yMin + Group.Margin.y;
                }
            } else if (rect.yMax + Group.Margin.y > canvasRect.yMax) {
                rect.y = canvasRect.yMax - Group.Margin.y - rect.height;
            }
            RectTransform.localPosition = new Vector3(rect.x + rect.width * Group.Pivot.x, rect.y + rect.height * Group.Pivot.y);
        }

        //protected sealed override void OnRectTransformDimensionsChange() {
        //    base.OnRectTransformDimensionsChange();
        //    Apply();
        //}

        protected sealed override void OnTransformParentChanged() {
            base.OnTransformParentChanged();
            Apply();
        }

        private void Update() {
            if (m_LastScale != RectTransform.localScale) {
                Apply();
            }
        }

        protected sealed override void OnEnable() {
            base.OnEnable();
            if (m_IsStart) {
                Apply();
            }
        }

        protected sealed override void Start() {
            base.Start();
            m_IsStart = true;
            Apply();
        }

        void ITipsUIBehaviour.Initalize(ITipsGroup group, Vector3 buttonWorldPosition, Rect buttonRect) {
            Group = group;
            ButtonWorldPosition = buttonWorldPosition;
            m_ButtonRect = buttonRect;
            Canvas = gameObject.GetComponentInParent<Canvas>(true);
            Apply();
        }
    }
}
